package com.example.springbootdockerdemo.aspect;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.example.springbootdockerdemo.annotation.LogAop;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

/**
 * @ClassName LogAop
 * @Author Chengy
 * @Date 2021/11/22 15:52
 * @Version 1.0
 */

@Aspect
@Component
@Slf4j
public class LogAspect {


    @Pointcut("@annotation(com.example.springbootdockerdemo.annotation.LogAop)")
    public void resLog() {
    }


    @Around("resLog()")
    public Object around(ProceedingJoinPoint joinPoint) {

        long begin = System.currentTimeMillis();
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();


        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        LogAop logAop = method.getAnnotation(LogAop.class);


        String value = logAop.value();


        //可以添加日志表
        //记录用户 轨迹
        // 先进 filter 在进 interceptor 最后进 aop
        // 可以通过 token 拦截，然后 通过token 获取用户数据 在aop 中 获取 user 数据


        log.info("请求开始");
        log.info("请求连接 {}", request.getRequestURL().toString());
        log.info("接口描述 {}", value);
        log.info("请求类型 {}", request.getMethod());
        log.info("请求方法 {}.{}", signature.getDeclaringTypeName(), signature.getName());
        log.info("请求ip {}", request.getRemoteAddr());
        log.info("请求入参 {}", JSONObject.toJSONString(joinPoint.getArgs()));
        log.info("请求token {}", request.getHeader("token"));
        Object result = null;

        try {
            result = joinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }

        long end = System.currentTimeMillis();
        log.info("请求耗时 {}", end - begin);
        log.info("请求返回 {}", JSON.toJSON(result));
        log.info("请求结束");

        return result;
    }


}
